/*
 * Copyright (c) 2023 Beijing HuaQing YuanJian Education Technology Co., Ltd
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include "cJSON.h"

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "mynfc.h"
#include "mywifi.h"

#include "../../inc/sys_config.h"

//osThreadId_t Task1_ID; // 任务1设置为低优先级任务
//#define TASK_STACK_SIZE (1024 * 10)

#define MAX_LEN 256
#define PORT_NUMBER 8888
#define DEVICE_ID "device_id"
#define PARAM     "parameter"
#define SSID      "wifi_ssid"
#define PASSWD    "wifi_passwd"
#define IP        "wifi_ip"
#define PORT      "port_id"

#define CLIENT_IP "client_ip"

#define SMART_CAR "smart_car"

static int parseWifi(char *ssid, char *passwd,char *clientip)
{
    uint8_t tmp = nfcBuf[NDEF_PROTOCOL_MEG_CONFIG_OFFSET];
    uint8_t sr = 0;
    uint8_t il = 0;
    int ret = -1;
    int id_len = 0;
    int payload_len = 0;
    uint8_t *payload, *txt;
    /*控制位的第5位，如果置位为1，说明payload只有1个字节，置位为0，payload有4个字节*/
    sr = tmp & 0x10;
    /*控制位的第4位，如果置位为1，说明ID length和ID都有，置位为0，说明都没有*/
    il = tmp & 0x08;
    
    if (sr == 0x10)
    {
        payload_len = nfcBuf[NDEF_PROTOCOL_DATA_LENGTH_OFFSET];
    }
    else
    {
        payload_len = nfcBuf[NDEF_PROTOCOL_DATA_LENGTH_OFFSET] << 24 | \
                     nfcBuf[NDEF_PROTOCOL_DATA_LENGTH_OFFSET2] << 16 | \
                     nfcBuf[NDEF_PROTOCOL_DATA_LENGTH_OFFSET3] << 8 | \
                     nfcBuf[NDEF_PROTOCOL_DATA_LENGTH_OFFSET4];
    }

    printf("sr = 0x%x, il = 0x%x, payloadlen is 0x%x\n",sr, il, payload_len);

    payload = (uint8_t *)malloc(payload_len + 1);
    memset(payload, 0, payload_len + 1);
    /*payload只有1个字节, ID length和ID都没有*/
    if (sr == 0x10 && il == 0x00)
    {
        memcpy(payload, nfcBuf + NDEF_PROTOCOL_DATA_TYPE_OFFSET, payload_len);
    }
    /*payload只有1个字节, ID length和ID都有*/
    else if(sr == 0x10 && il == 0x08)
    {
        id_len = nfcBuf[NDEF_PROTOCOL_ID_LENGTH_OFFSET];
        memcpy(payload, nfcBuf + NDEF_PROTOCOL_DATA_TYPE_OFFSET + id_len, payload_len);
    }
    /*payload只有4个字节, ID length和ID都没有*/
    else if(sr == 0x00 && il == 0x00)
    {
        memcpy(payload, nfcBuf + NDEF_PROTOCOL_DATA_TYPE_OFFSET + 3, payload_len);
    }
    /*payload只有4个字节, ID length和ID都有*/
    else if(sr == 0x00 && il == 0x00)
    {
        id_len = nfcBuf[NDEF_PROTOCOL_ID_LENGTH_OFFSET + 3];
        memcpy(payload, nfcBuf + NDEF_PROTOCOL_DATA_TYPE_OFFSET + id_len + 3, payload_len);
    }

    /*加0x2 0x65 0x6e*/
    txt = payload + 3;
    printf("txt = %s\n", txt);

    cJSON *root = cJSON_Parse((char*)txt);
    cJSON *parameter = cJSON_GetObjectItem(root, PARAM);
    cJSON *mySsid = NULL;
    cJSON *myPassword = NULL;
    cJSON *client_ip = NULL;
    if (root != NULL && parameter == NULL)
    {
        mySsid = cJSON_GetObjectItem(root, "ssid");
        myPassword = cJSON_GetObjectItem(root, "passwd");
        client_ip = cJSON_GetObjectItem(root, "client_ip");
    }
    else if(root != NULL && parameter != NULL)
    {
        mySsid = cJSON_GetObjectItem(parameter, SSID);
        myPassword = cJSON_GetObjectItem(parameter, PASSWD);
        client_ip = cJSON_GetObjectItem(parameter, CLIENT_IP);
    }
    if (root != NULL && mySsid != NULL && myPassword != NULL) {
        printf("ssid = %s, password = %s,client_ip = %s\n", mySsid->valuestring, myPassword->valuestring,client_ip->valuestring);
        strcpy(ssid, mySsid->valuestring);
        strcpy(passwd, myPassword->valuestring); 
        strcpy(clientip, client_ip->valuestring); 
        ret = 0;
    }
    else
    {
        printf("Can not parse\n");
        ret = -1;
    }
    cJSON_Delete(root);
    free(payload);
    root = NULL;
    mySsid = NULL;
    myPassword = NULL;
    payload = NULL;
    free(nfcBuf);
    printf("Get ssid = %s, password = %s success.\n", ssid, passwd);
    return ret;
}

static int  writeInfoToNfc(char *ssid, char *password, char *ip, int port)
{
    char *str;
    int len;
    uint8_t *data;
    int ret;

    cJSON* cjson_root = cJSON_CreateObject();
    cJSON_AddStringToObject(cjson_root, DEVICE_ID, SMART_CAR);
    cJSON* cjson_param = cJSON_CreateObject();
    cJSON_AddStringToObject(cjson_param, SSID, ssid);
    cJSON_AddStringToObject(cjson_param, PASSWD, password);
    cJSON_AddStringToObject(cjson_param, IP, ip);
    cJSON_AddNumberToObject(cjson_param, PORT, port);
    cJSON_AddItemToObject(cjson_root, PARAM, cjson_param);

    str = cJSON_Print(cjson_root);
    printf("wifi Info is %s\n", str);

    len = strlen(str);
    printf("Data len is 0x%x\n", len);

    data = (uint8_t *)malloc(len + NDEF_HEADER_SIZE + NDEF_PROTOCOL_HEAD_SIZE + NDEF_PROTOCOL_PAYLOAD_HEAD_SIZE + 1);
    memset(data, 0, len + NDEF_HEADER_SIZE + NDEF_PROTOCOL_HEAD_SIZE + NDEF_PROTOCOL_PAYLOAD_HEAD_SIZE + 1);

    data[NDEF_PROTOCOL_HEADER_OFFSET] = 0x3;
    data[NDEF_PROTOCOL_LENGTH_OFFSET] = len + NDEF_PROTOCOL_HEAD_SIZE + NDEF_PROTOCOL_PAYLOAD_HEAD_SIZE;
    data[NDEF_PROTOCOL_MEG_CONFIG_OFFSET] = 0xd1;
    data[NDEF_PROTOCOL_DATA_TYPE_LENGTH_OFFSET] = 1;
    data[NDEF_PROTOCOL_DATA_LENGTH_OFFSET] = len + NDEF_PROTOCOL_PAYLOAD_HEAD_SIZE;
    data[NDEF_PROTOCOL_TYPE_OFFSET] = 'T';
    data[NDEF_PROTOCOL_DATA_TYPE_OFFSET] = 0x2;
    data[NDEF_PROTOCOL_DATA_TYPE_OFFSET + 1] = 0x65;
    data[NDEF_PROTOCOL_DATA_TYPE_OFFSET + 2] = 0x6e;
    memcpy(data + NDEF_PROTOCOL_DATA_TYPE_OFFSET + 3, str, len);

    cJSON_Delete(cjson_param);
    cJSON_Delete(cjson_root);
    cjson_root = NULL;

    ret = writeNfc(data);
    if (0 != ret)
    {
        printf("Write nfc failed.\n");
        return ret;
    }

    return ret;
}

void configWifi(void)
{
    char ssid[MAX_LEN] = {0};
    char passwd[MAX_LEN] ={0};
    char client_ip[MAX_LEN] = {0};
    int ret = -1;

    printf("Config wifi Start.\n");

    ret = i2cInit();
    if (0 != ret)
    {
        printf("Init i2c failed.\n");
        return;
    }
    memset(g_IP_Addr, 0, 20);

    while( 0 == strlen(g_IP_Addr))
    {
        ret = readNfc();
        if (0 != ret)
        {
            printf("Read NFC data failed.\n");
            sleep(1);
            continue;
        }
        ret = parseWifi(ssid, passwd,client_ip);
        if (0 != ret)
        {
            printf("Parse wifi ssid password failed.\n");
            sleep(1);
            continue;
        }
        
        gloabel_client_addr.sin_addr.s_addr = inet_addr(client_ip);
        

        ret = connectToWifi(ssid, passwd);
        if (0 != ret)
        {
            printf("Config wifi failed.\n");
            sleep(1);
            continue;
        }
    }

    printf("Config wifi success.\n");
#if 0
    ret = writeInfoToNfc(ssid, passwd, g_IP_Addr, PORT_NUMBER);
    if (0 != ret)
    {
        printf("Write ip and port failed.\n");
        return;
    }

#endif
    printf("Write ip success.\n");
}

/*
void Task1(void)
{
    configWifi();
    while (1) {
        sleep(1); // 1 s
    }
}
static void nfcConfigWifi(void)
{
    printf("Enter nfcConfigWifi()!\r\n");
    osThreadAttr_t options;
    options.name = "thread_1";
    options.attr_bits = 0;
    options.cb_mem = NULL;
    options.cb_size = 0;
    options.stack_mem = NULL;
    options.stack_size = TASK_STACK_SIZE;
    options.priority = osPriorityNormal;

    Task1_ID = osThreadNew((osThreadFunc_t)Task1, NULL, &options);
    if (Task1_ID != NULL) {
        printf("ID = %d, Create Task1_ID is OK!\r\n", Task1_ID);
    }
}
SYS_RUN(nfcConfigWifi);
*/